cc.Class({
    extends: cc.Component,

    properties: {
        nameLabel: {
            default: null,
            type: cc.Label
        },
        hpBar: {
            default: null,
            type: cc.ProgressBar
        },
        tankSprite: {
            default: null,
            type: cc.Sprite
        },
        cannonNode: {
            default: null,
            type: cc.Node
        },
        spriteFrame: {
            default: [],
            type: cc.SpriteFrame
        },
    },

    // use this for initialization
    onLoad: function () {
        //this.nameLabel.String = this.id;
    },

    init: function (game, id, type, arenaId, isLocal, x, y, hp) {
        this.game = game;
        this.id = id;
        this.type = type;
        this.speed = 5;
        this.arenaId = arenaId;
        this.w = 60;
        this.h = 80;
        this.baseAngle = this.getRandomInt(0, 360);
        //Make multiple of rotation amount
        this.cannonAngle = 0;
        this.node.x = this.x = x;
        this.node.y = this.y = y;
        this.dir = [0, 0, 0, 0];
        this.isLocal = isLocal;
        this.hp = hp;
        this.dead = false;
        this.nameLabel.string = this.id;
        this.tankSprite.spriteFrame = this.spriteFrame[this.type - 1];
        this.materialize();
    },

    onDestroy: function () {
        this.game.deleteTank(this.id);
    },

    materialize: function () {
        this.refresh();
        if (this.isLocal) {
            this.setControls();
        }
    },

    refresh: function () {

        // if (this.isMoving()) {
        //     this.$info.addClass('fade');
        // } else {
        //     this.$info.removeClass('fade');
        // }

        // this.$info.find('.hp-bar').css('width', this.hp + 'px');
        // this.$info.find('.hp-bar').css('background-color', getGreenToRed(this.hp));
        this.node.rotation = this.baseAngle;
        this.cannonNode.rotation = this.cannonAngle - this.baseAngle;
        this.hpBar.node.color = this.getGreenToRed(this.hp);
        this.hpBar.progress = this.hp / 100;
    },

    getRandomInt: function (min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
    },

    getGreenToRed: function (percent) {
        var r = percent < 50 ? 255 : Math.floor(255 - (percent * 2 - 100) * 255 / 100);
        var g = percent > 50 ? 255 : Math.floor((percent * 2) * 255 / 100);
        return new cc.Color(r, g, 0);
        // return 'rgb(' + r + ',' + g + ',0)';
    },

    updateJoystick: function () {
        var dis = cc.pDistance(cc.v2(0, 0), this.stickPos);
        if (dis > this.stickRadius) {
            var rate = this.stickRadius / dis;
            this.stickPos = cc.v2(this.stickPos.x * rate, this.stickPos.y * rate);
        }
        this.stick.setPosition(this.stickPos);
        if (this.stickPos.x != 0 || this.stickPos.y != 0) {
            this.baseAngle = Math.atan2(this.stickPos.x, this.stickPos.y) * 180 / Math.PI;
        }
    },

    setControls: function () {
        var self = this;
        var joystick = this.joystick = cc.find("Canvas/joystick");
        var canvas = cc.find("Canvas");
        var arena = cc.find("Canvas/arena");
        var stick = this.stick = cc.find("Canvas/joystick/stick");
        this.stickRadius = 50;
        joystick.active = true;
        self.stickPos = cc.p(0, 0);
        self.isMoving = false;
        self.stickTouchId = null;
        joystick.on(cc.Node.EventType.TOUCH_START, function (event) {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            self.stickTouchId = touches[0].getID();
            self.isMoving = true;
            self.stickPos = self.stick.parent.convertToNodeSpaceAR(touchLoc);
            self.updateJoystick();
        }, self.node);
        joystick.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            // self.touchLocationDisplay.textKey = i18n.t("cases/03_gameplay/01_player_control/On/OnTouchCtrl.js.1") + Math.floor(touchLoc.x) + ', ' + Math.floor(touchLoc.y) + ')';
            self.stickPos = self.stick.parent.convertToNodeSpaceAR(touchLoc);
            self.updateJoystick();
        }, self.node);
        joystick.on(cc.Node.EventType.TOUCH_END, function (event) {
            self.isMoving = false; // when touch ended, stop moving
            self.stickPos = cc.v2(0, 0);
            self.stickTouchId = null;
            self.updateJoystick();
        }, self.node);
        joystick.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
            self.isMoving = false; // when touch ended, stop moving
            self.stickPos = cc.v2(0, 0);
            self.stickTouchId = null;
            self.updateJoystick();
        }, self.node);

        canvas.on(cc.Node.EventType.TOUCH_END, function (event) {
            var rect = joystick.getBoundingBox();
            var touches = event.getTouches();
            var touchLoc = null;
            for (var i in touches) {
                var touch = touches[i];
                var loc = touch.getLocation();
                var nodeloc = canvas.convertToNodeSpaceAR(loc);
                if (nodeloc.y > rect.yMax && nodeloc.x > rect.xMax) {
                    touchLoc = nodeloc;
                    break;
                }
            }
            if (touchLoc) {
                self.setCannonAngle(touchLoc);
                self.shoot();
            }
        });
    },

    move: function () {
        if (this.dead) {
            return;
        }
        var moveX = this.speed * (this.stickPos.x / this.stickRadius);
        var moveY = this.speed * (this.stickPos.y / this.stickRadius);
        // cc.log("moveX"+moveX +"  moveY"+moveY);
        if (this.node.x + moveX > (- cc.Config.WIDTH / 2 + cc.Config.ARENA_MARGIN) && (this.node.x + moveX) < (cc.Config.WIDTH / 2 - cc.Config.ARENA_MARGIN)) {
            this.node.x += moveX;
        }
        if (this.node.y + moveY > (- cc.Config.HEIGHT / 2 + cc.Config.ARENA_MARGIN) && (this.node.y + moveY) < (cc.Config.HEIGHT / 2 - cc.Config.ARENA_MARGIN)) {
            this.node.y += moveY;
        }
        // cc.log("moveX  " + moveX);

        this.refresh();
    },


    setCannonAngle: function (point) {
        var tank = { x: this.node.x, y: this.node.y };
        var deltaX = point.x - tank.x;
        var deltaY = point.y - tank.y;
        this.cannonAngle = -Math.atan2(deltaY, deltaX) * 180 / Math.PI + 90;
        cc.log("this.cannonAngle " + this.cannonAngle);
        //this.cannonAngle = (this.cannonAngle - this.baseAngle + 360) % 360;
    },

    shoot: function () {
        if (this.dead) {
            return;
        }

        //Emit ball to server
        var serverBall = {};
        //Just for local balls who have owner
        serverBall.alpha = this.cannonAngle * Math.PI / 180; //angle of shot in radians	
        //Set init position
        var cannonLength = 60;
        var deltaX = cannonLength * Math.sin(serverBall.alpha);
        var deltaY = cannonLength * Math.cos(serverBall.alpha);

        serverBall.ownerId = this.id;
        serverBall.x = this.node.x + deltaX;
        serverBall.y = this.node.y + deltaY;

        cc.log("send shoot=" + JSON.stringify(serverBall));
        cc.Network.socket.emit('shoot', serverBall);
    },

    sendData: function () {
        //Send local data to server
        var gameData = {};

        //Send tank data
        var t = {
            id: this.id,
            x: this.node.x,
            y: this.node.y,
            baseAngle: this.baseAngle,
            cannonAngle: this.cannonAngle
        };
        gameData.tank = t;
        //Client game does not send any info about balls, 
        //the server controls that part 
        // cc.log("send sync="+JSON.stringify(gameData));
        cc.Network.socket.emit('sync', gameData);
    },

});
